﻿
#include <ghc/filesystem.hpp>
#include <mio.hpp>

#include "lua_filewatcher.hpp"
#include "utils_file.h"

void mqtt_lua_call(const char* fname, const char* arg1, const char* arg2);

class FileWatchListener : public efsw::FileWatchListener
{
public:
    FileWatchListener(const char* logpath, const umap_ss& keywords, int skipN, const char* line_handle)
    {
        this->line_handle = line_handle;
        this->skipN       = skipN;
        this->keywords    = keywords;
        this->logpath     = logpath;

        ghc::filesystem::path full_path(logpath);

        filename = full_path.filename().string();

        int matched_line_cnt = 1;

        read_lines(logpath, fileOffset, [&](const std::string& line) {
            std::string key;
            if ((key = match(line, keywords)).size() > 0 && matched_line_cnt++ > skipN)
                mqtt_lua_call(this->line_handle.c_str(), key.c_str(), line.c_str());
        });
    }

    void handleFileAction(efsw::WatchID      watchid,
                          const std::string& dir,
                          const std::string& filename,
                          efsw::Action       action,
                          std::string        oldFilename) override
    {
        if (action == efsw::Actions::Modified && this->filename == filename)
        {
            read_lines(logpath.c_str(), fileOffset, [&](const std::string& line) {
                std::string key;
                if ((key = match(line, keywords)).size() > 0)
                    mqtt_lua_call(this->line_handle.c_str(), key.c_str(), line.c_str());
            });
        }
    }

private:
    int64_t fileOffset = 0;

    std::string filename;

    std::string line_handle;

    std::string logpath;
    umap_ss     keywords;
    int         skipN;
};

FileWatcher* newFileWatcher(const char* logpath, const umap_ss keywords, int skipN, const char* line_handle)
{
    ghc::filesystem::path full_path(logpath);
    if (!ghc::filesystem::exists(full_path))
    {
        printf("Executable path does not exist");
        return nullptr;
    }
    FileWatchListener* watcher = new FileWatchListener(logpath, keywords, skipN, line_handle);

    auto p = new FileWatcher();
    p->watch(full_path.parent_path().string(), watcher);
    return p;
}